﻿using System;
using System.Collections.Generic;
using System.Text;

namespace ChemicalEquilibrium
{
    /// <summary>
    /// 离子泵
    /// </summary>
    public class IonicPump
    {
        Queue<Reactant> Pumps;
        Queue<Reactant>[] IonsIn, IonsOut;
        int[] Counts, Thresholds;

        /// <summary>
        /// 构造离子泵
        /// </summary>
        /// <param name="pumps">离子泵</param>
        /// <param name="ionsIn">膜内离子</param>
        /// <param name="ionsOut">膜外离子</param>
        /// <param name="counts">泵出或泵入离子的数量, 大于0表示泵入,小于0表示泵出</param>
        /// <param name="thresholds">泵的开放阈值, 以膜内离子数为准.</param>
        public IonicPump(Queue<Reactant> pumps, Queue<Reactant>[] ionsIn, Queue<Reactant>[] ionsOut, int[] counts, int[] thresholds)
        {
            this.Pumps = pumps;
            this.IonsIn = ionsIn;
            this.IonsOut = ionsOut;
            this.Counts = counts;
            this.Thresholds = thresholds;
        }

        /// <summary>
        /// 运输离子
        /// </summary>
        public void Transport()
        {
            int length = this.IonsIn.Length;

            bool transport = true;

            for (int i = 0; i < length; i++)
            {
                Queue<Reactant> ionsIn = this.IonsIn[i];
                int count = this.Counts[i];
                int threshold = this.Thresholds[i];

                if (count > 0)
                {
                    transport = transport && ionsIn.Count < threshold;
                }
                else if (count < 0)
                {
                    transport = transport && ionsIn.Count > threshold;
                }

                if (!transport) break;
            }

            if (transport)
            {
                for (int i = 0; i < length; i++)
                {
                    Queue<Reactant> ionsIn = this.IonsIn[i];
                    Queue<Reactant> ionsOut = this.IonsOut[i];
                    int count = this.Counts[i] * this.Pumps.Count;

                    if (count > 0)
                    {
                        for (int j = 0; j < count; j++)
                        {
                            if (ionsOut.Count == 0) break;
                            ionsIn.Enqueue(ionsOut.Dequeue());
                        }
                    }
                    else if (count < 0)
                    {
                        for (int j = 0; j < -count; j++)
                        {
                            if (ionsIn.Count == 0) break;
                            ionsOut.Enqueue(ionsIn.Dequeue());
                        }
                    }
                }
            }
        }
    }
}
